package ch.sfug.player{

	

	import ch.sfug.events.TimeProgressEvent;
	import ch.sfug.net.loader.AbstractLoader;
	import ch.sfug.player.IExternalPlayer;
	import ch.sfug.player.IMediaPlayer;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.media.SoundTransform;
	import flash.net.URLRequest;




	/**
	* player for automatically choosing the right player
	* can host serveral players and decide per filetype which player to use
	* 
	* forwards hosted events
	*/
	public class ExternalPlayerProxy extends EventDispatcher implements IMediaPlayer,IExternalPlayer {
		//{ ATTRIBUTES
		
		private var _mappings:Array;

		protected var _player:IMediaPlayer;
		protected var _soundt:SoundTransform;

		
		//}

		//{ GETTER-SETTER
		

		public function get loader():AbstractLoader { return IExternalPlayer(_player).loader; }
 		/** @private */
		public function set loader(newValue:AbstractLoader):void{
			//this._loader = newValue;
		}
		
		public function get player():IMediaPlayer { return _player; }
		
		public function set player(value:IMediaPlayer):void {
			_player = value;
		}
		public function get soundTransform():SoundTransform {
			return _soundt;
		}
		public function set soundTransform( st:SoundTransform ):void {
			_soundt = st;
			if (_player) _player.soundTransform = st;
		}
		public function get time():Number {
			if (_player != null)
				return _player.time;
			return 0;
		}
		
		public function get duration():Number{
			if (_player != null)
				return _player.duration;
			return 0;
		}
		//}


		//{ INIT
		public function ExternalPlayerProxy() {
			super();
			_soundt = new SoundTransform();
			_mappings = new Array();
		}

		//}

		//{ METHODS
		
		/**
		* adds a custom player mapping
		* @param	player	player reference to use
		* @param	pattern	pattern zb. *.mp3 or *.mp3;*.wav
		*/
		public function addMapping(player:IMediaPlayer, pattern:String):void {
			var pm:PlayerMatch = new PlayerMatch();
			pm.player = player;
			
			var sp:String = pattern.split(";").join("|");
			sp = sp.replace(/\./g, "\\.");
			sp = sp.replace(/\*/g, ".+?");
			sp = "(" + sp + ")$";
			
			pm.pattern = new RegExp(sp);
			//trace(pm.pattern.source);
			_mappings.push(pm);
		}
		
		/**
		* start play
		*/
		public function play():void{
			if (_player != null)
				_player.play();
		}
		/**
		* pause player
		*/
		public function pause():void{
			if (_player != null)
				_player.pause();
		}
		/**
		* stops the player
		*/
		public function stop():void{
			if (_player != null)
				_player.stop();
		}
		
		public function end():void
		{
			if (_player != null)
				_player.end();
		}
		/**
		* seek to specified time
		* @param	time	ms to play
		*/
		public function seek(time:Number):void{
			if (_player != null)
			{
				_player.seek(time);
			}
		}
		/**
		* checks if the player is playing
		* @return	
		*/
		public function isPlaying():Boolean{
			if (_player != null)
				return _player.isPlaying();
			return false;
		}
		/**
		* checks if the player is paused
		* @return	
		*/
		public function isPaused():Boolean {
			if (_player != null)
				return _player.isPaused();
			return false;
		}
		/**
		* checks if the player is stopped
		* @return	
		*/
		public function isStopped():Boolean{
			if (_player != null)
				return _player.isStopped();
			return false;
				
		}
		/**
		* checks if the palyer ist at end
		* @return	
		*/
		public function isAtEnd():Boolean{
			if (_player != null)
				return _player.isAtEnd();
			return false;
		}
		/**
		* 
		* @param	url	
		*/
		public function load(url:URLRequest):void {
			var pl:IMediaPlayer;
			for each (var pm:PlayerMatch in _mappings)
			{
				if (pm.match(url.url))
				{
					pl = pm.player;
					pl.soundTransform = _soundt;
					break;
				}
			}
			
			if (pl != null)
			{
				this.player = pl;
			}
			else
			{
				throw new Error("NO MATCHING PLAYER FOUND:" +url.url);
			}
			
			IExternalPlayer(player).load(url);
			
		}
		
		override public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void {
			super.addEventListener(type, listener, useCapture, priority, useWeakReference);
			
			for each (var pm:PlayerMatch in _mappings)
				pm.player.addEventListener(type, handleEvent, useCapture, priority);
		}
		override public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void {
			super.removeEventListener(type, listener, useCapture);
			
			for each (var pm:PlayerMatch in _mappings)
				pm.player.removeEventListener(type, handleEvent, useCapture);
		}
		public function addLoaderListener(type:String, func:Function):void
		{
			for each (var pm:PlayerMatch in _mappings)
			{
				trace("(ExternalPlayerProxy.addLoaderListener) "+pm.player);
				IExternalPlayer(pm.player).addLoaderListener(type, func);
			}
		}
		public function removeLoaderListener(type:String, func:Function):void
		{
			for each (var pm:PlayerMatch in _mappings)
				IExternalPlayer(pm.player).removeLoaderListener(type, func);
		}
		//}

		//{ PRIVATE METHODS
		private function handleEvent(e:Event):void
		{
			dispatchEvent(e);
		}
			
		
		//}
	}

}


